﻿using System;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace Cataloger
{
    /// <summary>
    /// Klasa reprezentująca wpis w pliku archiwalnym odnosi się tak do pliku jak i folderu.
    /// Obiekty klasy PlikArchiwumRar oraz PlikArchiwumZip gromadzą obiekty tej klasy.
    /// </summary>
    [Serializable]
    public class ArchiwumEntry:IObiektCatalogera,IInfo
    {
		#region Fields (7) 

        /// <summary>
        /// Czy dany wpis jest folderem. Jeżeli tak to TRUE, w przypadku
        /// gdy jest plikiem to FALSE.
        /// </summary>
        bool czyFolder;
        DateTime dataModyfikacj;
        public static ImageHashtable il = new ImageHashtable();
        /// <summary>
        /// Nazwa wpisu bedąca scieżką do danego pliku/folderu wewnątrz archiwum
        /// Przykładowo jezeli wpis jest plikiem o nazwie "test.txt" znajdującym się
        /// w folderze A który znajduje się w archiwum "ARCH.ZIP" to jego nazwa będzie
        /// wyglądała tak: "A/test.txt"
        /// </summary>
        string nazwa;
        /// <summary>
        /// Plik w którym znajduje się dany wpis np. dla wpisu bedącego
        /// plikiem "test.txt" znajdującego się w pliku "ARCH.ZIP", plikArchiwumRodzic
        /// będzie odniesiem do pliku "ARCH.ZIP"
        /// </summary>
        Plik plikArchiwumRodzic;
        /// <summary>
        /// Rozmiar pliku przed kompresją
        /// </summary>
        long rozmiarPrzed;


		#endregion Fields 

		#region Constructors (1) 

        /// <summary>
        /// Tworzy nowy obiekt klasy <see cref="ArchiwumEntry"/>.
        /// </summary>
        /// <param name="nazwa">Nazwa wpisu</param>
        /// <param name="dataMod">Data modyfikacji</param>
        /// <param name="rozmiarPrzed">Rozmiar przed kompresją</param>
        /// <param name="rozmiarPo">Rozmiar po kompresji</param>
        /// <param name="czyFolder">Jeżeli ustawione na true wpis jest folderem</param>
        /// <param name="skad">Plik w jakim znajduje się dany wpis</param>
        public ArchiwumEntry(string nazwa, DateTime dataMod, long rozmiarPrzed, bool czyFolder,Plik skad)
        {
            this.nazwa = nazwa;
            this.dataModyfikacj=dataMod;
            this.rozmiarPrzed=rozmiarPrzed;
            this.czyFolder = czyFolder;
            this.plikArchiwumRodzic = skad;
        }

		#endregion Constructors 

		#region Properties (12) 

        public bool CzyFolder
        {
            get { return czyFolder; }
        }

        public DateTime DataModyfikacj
        {
            get { return dataModyfikacj; }
        }

        public string Nazwa
        {
            get { return nazwa; }
        }

        /// <summary>
        /// Podaje tylko nazwe wpisu np tekst.txt
        /// </summary>
        public string NazwaBezSciezki
        {
            get { return Path.GetFileName(nazwa); }
        }

        /// <summary>
        /// Nosnik na jakim znajduje sie dany wpis archiwum
        /// </summary>
        public Nosnik Nosnik
        {
            get
            {
                return this.PlikArchiwumRodzic.Nosnik;
            }
        }

        public string Opis
        {
            get;
            set;
        }

        public Plik PlikArchiwumRodzic
        {
            get { return plikArchiwumRodzic; }
         }

        public long RozmiarPrzed
        {
            get { return rozmiarPrzed; }
        }


        public string Rozszerzenie
        {
            get
            {
                return Path.GetExtension(this.NazwaBezSciezki);
            }
        }

        public string Sciezka
        {
            get { return Path.Combine(plikArchiwumRodzic.Sciezka, this.nazwa); }
        }

        public string Typ
        {
            get
            {
                if (this.CzyFolder)
                {
                    return "Folder";
                }
                else
                {
                    FileInfoManager fim = new FileInfoManager();
                    return fim.GetFileTypeName(this.Rozszerzenie).Trim();
                }
            }
        }

		#endregion Properties 

		#region Methods (2) 

		// Public Methods (2) 

        /// <summary>
        /// Metoda tworząca opis obiektu tej klasy
        /// Zawiera informacje o nazwie, dacie, i rozmiarze
        /// </summary>
        /// <returns></returns>
        public string CalkowiteInfo
        {
            get
            {
                StringBuilder st = new StringBuilder();
                st.AppendLine("Nazwa: \t" + this.nazwa);
                st.AppendLine("Data: \t" + this.dataModyfikacj.ToShortDateString() + "  " + this.dataModyfikacj.ToShortTimeString());
                st.AppendLine("Rozmiar przed: \t" + this.rozmiarPrzed.ToProperUnit());
                return st.ToString();
            }
        }

        /// <summary>
        /// Wyswietla informacje o danym wpisie na listview
        /// </summary>
        /// <param name="listView1">The list view1.</param>
        public void ShowAEListView(ListView listView1)
        {
            il.AddImage(this.Rozszerzenie.ToLower(), new FileInfoManager().GetLargeFileTypeIcon(this.Rozszerzenie).ToBitmap());
            listView1.Items.Add(new ListViewItem(new string[] { this.NazwaBezSciezki,this.PlikArchiwumRodzic.Nosnik.Katalog.Nazwa,
                                                                this.PlikArchiwumRodzic.Nosnik.Nazwa, 
                                                                this.RozmiarPrzed.ToProperUnit(), this.DataModyfikacj.ToShortDateString(),
                                                                this.DataModyfikacj.ToShortDateString(), this.DataModyfikacj.ToShortDateString(), 
                                                                this.Rozszerzenie,this.Typ, "", "", 
                                                                this.Sciezka }));
            listView1.Items[listView1.Items.Count - 1].Tag = this;
            listView1.Items[listView1.Items.Count - 1].ImageKey = this.Rozszerzenie;
        }

		#endregion Methods 
    
        #region IObiektCatalogera Members


        public long Rozmiar
        {
            get { return RozmiarPrzed; }
        }

        public Kategoria Kategoria
        {
            get;
            set;
        }

        #endregion

        #region ILokalizacja Members

        public string SciezkaWKatalogu
        {
            get { return Path.Combine(this.PlikArchiwumRodzic.SciezkaWKatalogu, Nazwa); }
        }

        #endregion

        #region IInfo Members

        public string OpisWlasciwosci
        {
            get
            {
                StringBuilder st = new StringBuilder();
                st.AppendLine(String.Format("Nazwa: \t\t{0}", this.Nazwa));
                st.AppendLine("Sciezka: \t" + this.Sciezka);
                try
                {
                    st.AppendLine("Kategoria: \t" + this.Kategoria.Nazwa);
                }
                catch { }
                st.AppendLine("Rozmiar: \t" + this.Rozmiar.ToProperUnit());
                st.AppendLine("Data mod: \t" + this.DataModyfikacj.ToShortDateString() + "  " + this.DataModyfikacj.ToShortTimeString());
                st.AppendLine("Nosnik: \t" + this.Nosnik.Nazwa);
                st.AppendLine("Typ pliku:\t" + this.Typ);
                st.AppendLine("Katalog: \t" + this.PlikArchiwumRodzic.KataloG.Nazwa);

                return st.ToString();
            }
        }

        public string OpisToolTip
        {
            get
            {
                StringBuilder st = new StringBuilder();
                st.AppendLine(String.Format("{0} ({1})", this.Nazwa, this.Typ));
                st.AppendLine("Rozmiar: \t" + this.Rozmiar.ToProperUnit());

                return st.ToString();
            }
        }

        public string OpisStatusStrip
        {
            get
            {
                return string.Format("{0} ({1}), Rozmiar: {2}, Data: {3}",
                    this.Nazwa, this.Typ, this.Rozmiar.ToProperUnit(), this.dataModyfikacj.ToShortDateString());
            }
        }

        #endregion
    }
}
